package com.rc.evcharger.service.ticket;

import com.rc.evcharger.common.constant.SocketConstant;
import com.rc.evcharger.common.constant.level.UserLevelConstant;
import com.rc.evcharger.common.utils.DateHelper;
import com.rc.evcharger.component.UidGenerator;
import com.rc.evcharger.mapper.order.OrderDiscountRecordMapper;
import com.rc.evcharger.mapper.ticket.MemberTicketMapper;
import com.rc.evcharger.mapper.ticket.TenantTicketTypeMapper;
import com.rc.evcharger.model.order.OrderDiscountRecord;
import com.rc.evcharger.model.order.OrderInfo;
import com.rc.evcharger.model.ticket.MemberTicket;
import com.rc.evcharger.model.ticket.TenantTicketType;
import com.rc.evcharger.vo.cost.UserLevelPriceResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Create by Yang on 2021/5/22
 */
@Service
public class MemberTicketServiceImpl implements MemberTicketService {
    private static Logger logger = LoggerFactory.getLogger(MemberTicketServiceImpl.class);

    @Autowired
    private MemberTicketMapper memberTicketMapper;

    @Autowired
    private TenantTicketTypeMapper ticketTypeMapper;

    @Autowired
    private OrderDiscountRecordMapper orderDiscountRecordMapper;

    @Autowired
    private UidGenerator uidGenerator;

    @Override
    public MemberTicketMapper getMapper() {
        return memberTicketMapper;
    }


    /**
     * @param ticketSuitType 0整单满减优惠券 1服务费满减优惠卷
     * @param discountType   优惠类型,0立减 1打折 默认0
     * @param tenantCode
     * @param elecStationId
     * @param memberId
     * @param money          服务费or总费用
     * @return 最优金额、折扣
     */
    @Override
    public MemberTicket selectByOrderInfoAndTicketType(String ticketSuitType, String discountType, String tenantCode, Long elecStationId, Long memberId, BigDecimal money) {
        MemberTicket memberTicket = memberTicketMapper.selectByOrderInfoAndTicketType(ticketSuitType, discountType, tenantCode, elecStationId, memberId, money);
        if (memberTicket == null) {
            return null;
        }
        try {
            TenantTicketType tenantTicketType = ticketTypeMapper.selectByPrimaryKey(memberTicket.getTicketTypeId());
            //生效方式 0指定N天有效 1指定日期生效 默认0
            if (tenantTicketType.getEffectType().equals(SocketConstant.STR_CON0)) {
                int i = DateHelper.daysBetween(new Date(), memberTicket.getEndTime());
                if (i >= 0) {
                    logger.info("优惠券已过期,对应优惠券名称:{},会员ID:{}", tenantTicketType.getTicketName(), memberTicket.getMemberId());
                    return memberTicket;
                }
            } else {
                //计算差额天数
                int startDay = DateHelper.daysBetween(tenantTicketType.getEffectStartDate(), new Date());
                int endIDay = DateHelper.daysBetween(new Date(), tenantTicketType.getEffectEndDate());
                if (startDay >= 0 && endIDay >= 0) {
                    return memberTicket;
                }
            }
        } catch (ParseException e) {
            logger.error("selectByOrderInfoAndTicketType方法日期转化错误:{}", e.getMessage());
        }
        return null;
    }

    @Override
    public UserLevelPriceResult selectBestByOrderInfo(OrderInfo orderInfo) {
        if (orderInfo.getPayAmount().compareTo(BigDecimal.ZERO) <= 0) {
            return UserLevelPriceResult.emptyResult();
        }

        //是否优先使用优惠卷,0使用 1不使用,默认0
        if (SocketConstant.STR_CON1.equals(orderInfo.getTicketUsingType())) {
            return UserLevelPriceResult.emptyResult();
        }

        //总金额立减
        MemberTicket totalAmountMt = this.selectByOrderInfoAndTicketType(SocketConstant.STR_CON0, SocketConstant.STR_CON0, orderInfo.getTenantCode(), orderInfo.getElecStationId(), orderInfo.getMemberId(), orderInfo.getTotalMoney());
        //总金额折扣
        MemberTicket totalDiscountMt = this.selectByOrderInfoAndTicketType(SocketConstant.STR_CON0, SocketConstant.STR_CON1, orderInfo.getTenantCode(), orderInfo.getElecStationId(), orderInfo.getMemberId(), orderInfo.getTotalMoney());
        UserLevelPriceResult userLevelPriceResult0 = this.compareMemberTicket(totalAmountMt, totalDiscountMt, orderInfo);

        //服务费立减
        MemberTicket serviceAmountMt = this.selectByOrderInfoAndTicketType(SocketConstant.STR_CON1, SocketConstant.STR_CON0, orderInfo.getTenantCode(), orderInfo.getElecStationId(), orderInfo.getMemberId(), orderInfo.getTotalSeviceMoney());
        //服务费折扣
        MemberTicket serviceDiscountMt = this.selectByOrderInfoAndTicketType(SocketConstant.STR_CON1, SocketConstant.STR_CON1, orderInfo.getTenantCode(), orderInfo.getElecStationId(), orderInfo.getMemberId(), orderInfo.getTotalSeviceMoney());
        UserLevelPriceResult userLevelPriceResult1 = this.compareMemberTicket(serviceAmountMt, serviceDiscountMt, orderInfo);

        if (userLevelPriceResult0.getType() == UserLevelConstant.INVALID_DISCOUNT && userLevelPriceResult1.getType() == UserLevelConstant.INVALID_DISCOUNT) {
            return UserLevelPriceResult.emptyResult();
        }

        if (userLevelPriceResult0.getType() != UserLevelConstant.INVALID_DISCOUNT && userLevelPriceResult1.getType() == UserLevelConstant.INVALID_DISCOUNT) {
            return userLevelPriceResult0;
        }

        if (userLevelPriceResult0.getType() == UserLevelConstant.INVALID_DISCOUNT && userLevelPriceResult1.getType() != UserLevelConstant.INVALID_DISCOUNT) {
            return userLevelPriceResult1;
        }

        if (userLevelPriceResult0.getDiscountAmount().compareTo(userLevelPriceResult1.getDiscountAmount()) > 0) {
            return userLevelPriceResult0;
        } else if (userLevelPriceResult0.getDiscountAmount().compareTo(userLevelPriceResult1.getDiscountAmount()) == 0) {
            MemberTicket memberTicket0 = memberTicketMapper.selectByPrimaryKey(userLevelPriceResult0.getId());
            MemberTicket memberTicket1 = memberTicketMapper.selectByPrimaryKey(userLevelPriceResult1.getId());

            //如果优惠力度相同，则优先使用快过期优惠券
            if (memberTicket0.getEndTime().getTime() < memberTicket1.getEndTime().getTime()) {
                return userLevelPriceResult0;
            } else {
                return userLevelPriceResult1;
            }
        } else {
            return userLevelPriceResult1;
        }
    }

    @Override
    public UserLevelPriceResult updateTicketByOrderInfo(OrderInfo orderInfo) {

        UserLevelPriceResult userLevelPriceResult = UserLevelPriceResult.emptyResult();
        List<OrderDiscountRecord> orderDiscountRecords0 = new ArrayList<>();
        List<MemberTicket> memberTickets0 = new ArrayList<>();

        if (orderInfo.getPayAmount().compareTo(BigDecimal.ZERO) <= 0) {
            return userLevelPriceResult;
        }

        //是否优先使用优惠卷,0使用 1不使用,默认0
        if (StringUtils.isEmpty((orderInfo.getMemberTicketIds()))) {
            return userLevelPriceResult;
        }

        BigDecimal payAmount = orderInfo.getPayAmount();
        BigDecimal discountAmount = orderInfo.getDiscountAmount();

        //数组转long类型字符串
        List<String> memberTicketIds = Arrays.asList(orderInfo.getMemberTicketIds().split(","));
        List<Long> longs = memberTicketIds.stream().map(Long::valueOf).collect(Collectors.toList());

        List<MemberTicket> memberTickets = memberTicketMapper.listByOrderInfoAndTicketType(orderInfo.getPayAmount(), orderInfo.getTotalSeviceMoney(), longs);
        for (MemberTicket memberTicket : memberTickets) {

            TenantTicketType ticketType = memberTicket.getJoinTicketType();

            OrderDiscountRecord orderDiscountRecord = new OrderDiscountRecord();
            orderDiscountRecord.setTenantCode(orderInfo.getTenantCode());
            orderDiscountRecord.setOrderId(orderInfo.getOrderId());
            orderDiscountRecord.setCreatedTime(new Date());
            orderDiscountRecord.setDiscountNum(uidGenerator.genDiscountOrderNum("Y")); //优惠券号码
            orderDiscountRecord.setDiscountId(memberTicket.getMemberTicketId());
            orderDiscountRecord.setDiscountType(ticketType.getTicketSuitType());

            //当ticket_type=0时,优惠券适用的计算方式 0整单满减优惠券 1服务费满减优惠卷 2充电满折 3服务器满折 4代金券
            switch (ticketType.getTicketSuitType()) {
                case "0":
                    if (payAmount.compareTo(ticketType.getUseRequireAmount()) >= 0) {
                        payAmount = payAmount.subtract(ticketType.getDiscountAmount()); //优惠后金额
                        discountAmount = discountAmount.add(ticketType.getDiscountAmount()); //总优惠

                        orderDiscountRecord.setDiscountName("整单满减优惠券");
                        orderDiscountRecord.setDiscountAmount(ticketType.getDiscountAmount());
//                        orderDiscountRecordMapper.insertSelective(orderDiscountRecord);

                        memberTicket.setStatus("1");
                        memberTicket.setUsedTime(new Date());
//                        memberTicketMapper.updateByPrimaryKeySelective(memberTicket);

                        orderDiscountRecords0.add(orderDiscountRecord);
                        memberTickets0.add(memberTicket);
                    }
                    break;
                case "1":
                    if (orderInfo.getTotalSeviceMoney().compareTo(ticketType.getUseRequireAmount()) >= 0) {
                        payAmount = payAmount.subtract(ticketType.getDiscountAmount()); //优惠后金额
                        discountAmount = discountAmount.add(ticketType.getDiscountAmount()); //总优惠

                        orderDiscountRecord.setDiscountName("服务费满减优惠卷");
                        orderDiscountRecord.setDiscountAmount(ticketType.getDiscountAmount());
//                        orderDiscountRecordMapper.insertSelective(orderDiscountRecord);

                        memberTicket.setStatus("1");
                        memberTicket.setUsedTime(new Date());
//                        memberTicketMapper.updateByPrimaryKeySelective(memberTicket);

                        orderDiscountRecords0.add(orderDiscountRecord);
                        memberTickets0.add(memberTicket);
                    }
                    break;
                case "2":
                    if (payAmount.compareTo(ticketType.getUseRequireAmount()) >= 0) {
                        BigDecimal discountAmountPart = payAmount.subtract(payAmount.multiply(ticketType.getDiscount()).setScale(2, BigDecimal.ROUND_HALF_UP));
                        payAmount = payAmount.subtract(discountAmountPart); //优惠后金额
                        discountAmount = discountAmount.add(discountAmountPart); //总优惠

                        orderDiscountRecord.setDiscountName("充电满折");
                        orderDiscountRecord.setDiscountAmount(discountAmountPart);
//                        orderDiscountRecordMapper.insertSelective(orderDiscountRecord);

                        memberTicket.setStatus("1");
                        memberTicket.setUsedTime(new Date());
//                        memberTicketMapper.updateByPrimaryKeySelective(memberTicket);

                        orderDiscountRecords0.add(orderDiscountRecord);
                        memberTickets0.add(memberTicket);
                    }
                    break;
                case "3":
                    if (orderInfo.getTotalSeviceMoney().compareTo(ticketType.getUseRequireAmount()) >= 0) {
                        BigDecimal discountAmountPart = orderInfo.getTotalSeviceMoney().subtract(orderInfo.getTotalSeviceMoney().multiply(ticketType.getDiscount()).setScale(2, BigDecimal.ROUND_HALF_UP));
                        payAmount = payAmount.subtract(discountAmountPart); //优惠后金额
                        discountAmount = discountAmount.add(discountAmountPart); //总优惠

                        orderDiscountRecord.setDiscountName("服务费满折");
                        orderDiscountRecord.setDiscountAmount(discountAmountPart);
//                        orderDiscountRecordMapper.insertSelective(orderDiscountRecord);

                        memberTicket.setStatus("1");
                        memberTicket.setUsedTime(new Date());
//                        memberTicketMapper.updateByPrimaryKeySelective(memberTicket);

                        orderDiscountRecords0.add(orderDiscountRecord);
                        memberTickets0.add(memberTicket);
                    }
                    break;
                case "4":
                    payAmount = payAmount.subtract(ticketType.getDiscountAmount()); //优惠后金额
                    if (payAmount.compareTo(BigDecimal.ZERO) < 0) {
                        payAmount = BigDecimal.ZERO;
                    }
                    discountAmount = discountAmount.add(ticketType.getDiscountAmount()); //总优惠

                    orderDiscountRecord.setDiscountName("代金券");
                    orderDiscountRecord.setDiscountAmount(ticketType.getDiscountAmount());
//                    orderDiscountRecordMapper.insertSelective(orderDiscountRecord);

                    memberTicket.setStatus("1");
                    memberTicket.setUsedTime(new Date());
//                    memberTicketMapper.updateByPrimaryKeySelective(memberTicket);

                    orderDiscountRecords0.add(orderDiscountRecord);
                    memberTickets0.add(memberTicket);
                    break;
            }

        }

        //更新订单实付金额与优惠金额
        orderInfo.setTicketAmount(orderInfo.getPayAmount().subtract(payAmount)); //已使用优惠券金额
        orderInfo.setPayAmount(payAmount);
        orderInfo.setDiscountAmount(discountAmount);

        //防止负优惠
        if (orderInfo.getPayAmount().compareTo(BigDecimal.ZERO) == -1) {
            orderInfo.setPayAmount(BigDecimal.ONE);
        }


        userLevelPriceResult.setOrderDiscountRecords(orderDiscountRecords0);
        userLevelPriceResult.setMemberTickets(memberTickets0);

        return userLevelPriceResult;
    }


    /**
     * @param amountMt   立减优惠券
     * @param discountMt 折扣优惠券
     * @param orderInfo
     * @return 择优优惠券
     */
    protected UserLevelPriceResult compareMemberTicket(MemberTicket amountMt, MemberTicket discountMt, OrderInfo orderInfo) {

        if (amountMt == null && discountMt == null) {
            return UserLevelPriceResult.emptyResult();
        }

        //立减
        if (amountMt != null && discountMt == null) {
            UserLevelPriceResult userLevelPriceResult = new UserLevelPriceResult();
            userLevelPriceResult.setTenantCode(amountMt.getTenantCode());
            userLevelPriceResult.setType(UserLevelConstant.TICKET);
            userLevelPriceResult.setDiscountAmount(amountMt.getJoinTicketType().getDiscountAmount());
            userLevelPriceResult.setId(amountMt.getMemberTicketId());

            return userLevelPriceResult;
        }

        //折扣
        if (amountMt == null && discountMt != null) {
            UserLevelPriceResult userLevelPriceResult = new UserLevelPriceResult();
            userLevelPriceResult.setTenantCode(discountMt.getTenantCode());
            userLevelPriceResult.setType(UserLevelConstant.TICKET);
            userLevelPriceResult.setDiscountPrice(discountMt.getJoinTicketType().getDiscount());

            //计算优惠金额
            BigDecimal saleServiceAmount = discountMt.getJoinTicketType().getDiscount().multiply(orderInfo.getTotalSeviceMoney()).setScale(2, BigDecimal.ROUND_HALF_DOWN);
            BigDecimal discountAmount = orderInfo.getTotalSeviceMoney().subtract(saleServiceAmount);
            userLevelPriceResult.setDiscountAmount(discountAmount);
            userLevelPriceResult.setId(discountMt.getMemberTicketId());

            return userLevelPriceResult;
        }

        UserLevelPriceResult userLevelPriceResult = new UserLevelPriceResult();
        userLevelPriceResult.setType(UserLevelConstant.TICKET);
        //优惠类型,0立减 1打折 默认0
        BigDecimal saleServiceAmount = discountMt.getJoinTicketType().getDiscount().multiply(orderInfo.getTotalSeviceMoney()).setScale(2, BigDecimal.ROUND_HALF_DOWN);
        BigDecimal discountAmount = orderInfo.getTotalSeviceMoney().subtract(saleServiceAmount);

        if (amountMt.getJoinTicketType().getDiscountAmount().compareTo(discountAmount) > 0) {
            userLevelPriceResult.setDiscountAmount(amountMt.getJoinTicketType().getDiscountAmount());

            userLevelPriceResult.setId(amountMt.getMemberTicketId());
            return userLevelPriceResult;

            //相等
        } else if (amountMt.getJoinTicketType().getDiscountAmount().compareTo(discountAmount) == 0) {

            //如果优惠力度相同，则优先使用快过期优惠券
            if (amountMt.getEndTime().getTime() < discountMt.getEndTime().getTime()) {
                userLevelPriceResult.setDiscountAmount(amountMt.getJoinTicketType().getDiscountAmount());

                userLevelPriceResult.setId(amountMt.getMemberTicketId());
                return userLevelPriceResult;
            } else {
                userLevelPriceResult.setDiscountAmount(discountAmount);
                userLevelPriceResult.setId(discountMt.getMemberTicketId());

                return userLevelPriceResult;
            }
        } else {
            userLevelPriceResult.setDiscountAmount(discountAmount);
            userLevelPriceResult.setId(discountMt.getMemberTicketId());

            return userLevelPriceResult;
        }
    }

}
